// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace SnapObjects.Data
{
    /// <summary>
    ///     Provides methods to add data of embedded properties of TModel object to the IDataPacker object 
    ///     when using the IDataPacker.AddModel method or IDataPacker.AddModels method.
    /// </summary>
    /// <typeparam name="TModel">The type of a model class.</typeparam>
    public interface IDataIncludeSetter<TModel>
    {
        /// <summary>
        ///     Adds the data of an embedded property of TModel object to the IDataPacker object, and specifies a name for the data.
        /// </summary>
        /// <typeparam name="TKey">The type of the embedded property in the TModel object to be included.</typeparam>
        /// <param name="name">The name specified for the data.</param>
        /// <param name="property">A function used to specify the embedded property in the TModel object to be included.</param>
        /// <returns>Returns the current IDataIncludeSetter object.</returns>
        IDataIncludeSetter<TModel> Include<TKey>(string name, Func<TModel, TKey> property);

        /// <summary>
        ///     Adds the data of all embedded properties of TModel object to the IDataPacker object.
        /// </summary>
        void IncludeAll();
    }

    /// <summary>
    ///     Provides a series of methods needed after calling the IDataUnpacker.GetModel method or the 
    ///     IDataUnpacker.GetModels method. These methods can be used to get a TModel object or a collection 
    ///     of TModel objects, or continue to get data of embedded properties of TModel object from the IDataUnpacker object.
    /// </summary>
    /// <typeparam name="TModel">The type of a model class.</typeparam>
    public interface IDataIncludeGetter<TModel>
    {
        /// <summary>
        ///     Gets the data of all embedded properties of the TModel object from the IDataUnpacker object.
        /// </summary>
        /// <returns>Returns the current IDataIncludeGetter object.</returns>
        IDataIncludeGetter<TModel> IncludeAll();

        /// <summary>
        ///     Gets the data of an embedded property of the TModel object from the IDataUnpacker object.
        /// </summary>
        /// <typeparam name="TKey">The type of the embedded property in the TModel object to be included.</typeparam>
        /// <param name="name">The name specified for the data.</param>
        /// <param name="property">An expression used to specify the embedded property in the TModel object to be included.</param>
        /// <returns>Returns the current IDataIncludeGetter object.</returns>
        IDataIncludeGetter<TModel> Include<TKey>(string name, Expression<Func<TModel, TKey>> property);

        /// <summary>
        ///     Creates a TModel object which contains the first row of data from the IDataUnpacker object. Returns null if there is no data.
        /// </summary>
        /// <returns>A TModel object containing the data from the IDataUnpacker object. Returns null if there is no data.</returns>
        TModel FirstOrDefault();

        /// <summary>
        ///     Creates an <see cref="IList{TModel}"/> object which contains the data from the IDataUnpacker object.
        /// </summary>
        /// <returns>An <see cref="IList{TModel}"/> object containing the data from the IDataUnpacker object.</returns>
        IList<TModel> ToList();
    }
}
